<template>
	<uni-file-picker :file-extname="props.fileExtname" :fileMediatype="props.fileMediatype" :limit="props.limit"
		:mode="props.mode" v-model="imageList" :modelValue="imageList" @delete="onDelete" @fail="fail" @progress="progress"
		@select="upload" @success="success" :sourceType="sourceType"></uni-file-picker>
	<canvas v-if="waterMarkParams.display" canvas-id="waterMarkCanvas" :style="canvasStyle" />
</template>

<script setup>
	import {
		defineEmits,
		defineProps,
		reactive,
		ref,
		watch,
		computed,
		nextTick
	} from 'vue'
	import {
		commonUpload
	} from '@/config.js'
	import {
		getToken
	} from '@/utils/auth.js'
	import {
		onShow,
		onLoad
	} from '@dcloudio/uni-app'
	const emit = defineEmits(['progress', 'getSuccessUrl', 'progress', 'success', 'fail', 'onDelete'])
	const props = defineProps({
		// 图片类型
		fileExtname: {
			type: String,
			default: 'png,jpg,jpeg',
		},
		limit: {
			type: Number,
			default: 6,
		},
		// 宫格 列表 list
		mode: {
			type: String,
			default: 'grid',
		},
		// 上传的类型
		fileMediatype: {
			type: String,
			default: 'image',
		},
		// 图片回显
		imageList: {
			type: Object,
			default: {},
		},
		// 选择图片方式 相机/相册
		sourceType: {
			type: Array,
			default: ['album', 'camera']
		},
		// 是否添加水印
		addWaterMark: {
			type: Boolean,
			default: false
		}
	})
	console.log(props, 'props')
	const imageList = ref([])
	const cvsObj = reactive({
		time: '',
		date: '',
		week: '',
		address: ''
	})

	const waterMarkParams = reactive({
		display: false, // 控制 canvas 创建与销毁
		canvasWidth: 300, // 默认宽度
		canvasHeight: 225, // 默认高度
		contentHeight: 150, // 将要被绘制到图像中的矩形的高度(px)
	})

	watch(
		() => props.imageList,
		(newProps) => {
			if (typeof newProps.url === 'string' && newProps.url !== undefined) {
				imageList.value = JSON.parse(newProps.url).map((item, index) => {
					return {
						name: item,
						extname: newProps.extname,
						url: item,
					}
				})
			} else if (newProps.url !== undefined) {
				imageList.value = newProps.url.map((item, index) => {
					return {
						name: item,
						extname: newProps.extname,
						url: item,
					}
				})
			} else {
				imageList.value = [...newProps] // 直接赋值 页面回显不更新
			}
		}, {
			deep: true,
		},
	)

	const canvasStyle = computed(() => {
		return {
			position: 'fixed', // 移除到屏幕外
			left: '9999px',
			width: waterMarkParams.canvasWidth + 'px',
			height: waterMarkParams.canvasHeight + 'px',
		}
	})

	let materialImageDefine = ref([])
	const drawImg = ref('')
	// 获取上传状态
	const upload = async (e) => {
		uni.showLoading({
			title: '图片上传中...',
		})
		// 添加水印
		if (props.addWaterMark) {
			// 存储上传的图片
			const newArr = [...e.tempFiles.map((item) => item.path)]

			// 添加水印 获取到此次新增添加过水印的图片
			const imgFileArr = await callAddWaterMart(newArr)

			for (let i = 0; i < imgFileArr.length; i++) {
				uni.uploadFile({
					url: commonUpload, //上传图片的后端接口
					filePath: imgFileArr[i],
					name: 'file',
					formData: {
						user: 'test',
					},
					header: {
						Authorization: 'Bearer ' + getToken(),
					},
					success: (res) => {
						let data = JSON.parse(res.data)
						if (data.code == 200) {
							emit('getSuccessUrl', data.fileName)
						} else {
							uni.showToast({
								icon: 'none',
								title: data.msg,
							})
						}
						uni.hideLoading()
					},
					fail: () => {
						uni.hideLoading()
					},
				})
			}
		} else {
			// 不需要添加水印 直接上传
			let tempFilePaths = e.tempFilePaths
			for (let i = 0; i < tempFilePaths.length; i++) {
				uni.uploadFile({
					url: commonUpload, //上传图片的后端接口
					filePath: tempFilePaths[i],
					name: 'file',
					formData: {
						user: 'test',
					},
					header: {
						Authorization: 'Bearer ' + getToken(),
					},
					success: (res) => {
						let data = JSON.parse(res.data)
						materialImageDefine.value.push(data)
						if (data.code == 200) {
							emit('getSuccessUrl', data.fileName)
						} else {
							uni.showToast({
								icon: 'none',
								title: data.msg,
							})
						}
						uni.hideLoading()
					},
					fail: () => {
						uni.hideLoading()
					},
				})
			}
		}
	}

	// 获取上传进度
	const progress = (e) => {
		console.log(e)
		emit('progress')
	}

	// 上传成功
	const success = (e) => {
		console.log(e)
		uni.hideLoading()
		emit('success')
	}

	// 上传失败
	const fail = (e) => {
		console.log(e)
		uni.showToast({
			icon: 'error',
			title: '图片上传失败',
		})
		emit('fail')
		uni.hideLoading()
	}

	// 删除图片
	const onDelete = (e) => {
		let materialImage = []
		// 有回显
		if (imageList.value.length !== 0) {
			imageList.value.splice(e.index, 1)
			materialImage = imageList.value.map((v, index) => {
				return v.url
			})

		} else {
			// 无回显 直接新增
			materialImageDefine.value = materialImageDefine.value.filter((v) => {
				return v.originalFilename != e.tempFile.name
			})
			materialImage = materialImageDefine.value.map((v, index) => {
				return v.url
			})
		}
		emit('onDelete', materialImage)
	}

	// 获取时间
	const getDate = () => {
		let date = new Date();
		let year = date.getFullYear();
		let month = addZero(date.getMonth() + 1);
		let day = addZero(date.getDate());
		let hour = addZero(date.getHours());
		let minute = addZero(date.getMinutes());
		let second = addZero(date.getSeconds());
		let week = date.getDay();
		let weekCh = '';
		switch (week) {
			case 0:
				weekCh = '星期日';
				break;
			case 1:
				weekCh = '星期一';
				break;
			case 2:
				weekCh = '星期二';
				break;
			case 3:
				weekCh = '星期三';
				break;
			case 4:
				weekCh = '星期四';
				break;
			case 5:
				weekCh = '星期五';
				break;
			case 6:
				weekCh = '星期六';
				break;
		}
		cvsObj.time = hour + ':' + minute + ':' + second;
		cvsObj.date = year + '-' + month + '-' + day;
		cvsObj.week = weekCh;
	}

	// 缺0补齐
	const addZero = (num) => {
		return num < 10 ? '0' + num : num;
	}

	// 获取地址经纬度
	const getLocationFn = () => {
		return uni.getLocation({
			type: 'gcj02',
			// 是否解析地址信息
			geocode: true,
			isHighAccuracy: false, // 高精度定位，会调用gps获取高精度坐标
			success: res => {
				if (res.address) {
					cvsObj.address = res.address.country + res.address.city + res.address.district + res.address.street +
						res.address.streetNum + res.address.poiName
				}
			},
			fail: err => {
				console.log(err, 'getCurrentAddress fail')
			},
			complete: e => {
				console.log(e, 'getCurrentAddress complete')
			}
		})
	}

	// 因为有可能在相册中选择多个图片，所以这里要依次生成水印
	const callAddWaterMart = async (arr) => {
		let results = []
		if (arr.length > 0) {
			let addIndex = 0
			while (addIndex < arr.length) {
				const tempFilePath = await addWaterMarks(arr[addIndex])
				results.push(tempFilePath)
				addIndex = addIndex + 1
			}
		}
		return results
	}

	// 添加水印
	const addWaterMarks = (src) => {
		return new Promise((resolve, reject) => {
			// 获取图片信息，配置 canvas 尺寸
			uni.getImageInfo({
				src,
				success: res => {
					// 修复部分手机(如红米9)手机屏幕比较窄拍摄出来的图片水印压缩着覆盖的问题
					waterMarkParams.canvasWidth = Math.max(res.width, 886);
					waterMarkParams.canvasHeight = res.height;
					waterMarkParams.display = true
					// console.log('当前图片信息waterMarkParams：', waterMarkParams);
					// 等待 canvas 元素创建
					nextTick(() => {
						let context = uni.createCanvasContext("waterMarkCanvas", this);
						/* 绘制 */
						const {
							canvasWidth,
							canvasHeight,
							contentHeight
						} = waterMarkParams
						// 绘制前清空画布
						context.clearRect(0, 0, canvasWidth, canvasHeight);
						// 将图片src放到cancas内，宽高必须为图片大小
						context.drawImage(src, 0, 0, canvasWidth, canvasHeight, canvasWidth, canvasHeight);
						// 设置边框的透明度
						context.setGlobalAlpha(0.3);
						context.beginPath();
						// 绘制底部的白色背景
						context.rect(0, canvasHeight - contentHeight, canvasWidth, contentHeight);
						context.setFillStyle("white");
						context.fill();
						// 设置文字的透明度
						context.setGlobalAlpha(1);
						// 3.绘制底部的文字
						context.setFontSize(32);
						context.setTextAlign("left");
						context.setFillStyle("black");
						context.fillText(`拍摄时间：${cvsObj.date} ${cvsObj.week} ${cvsObj.time}`, 50, canvasHeight - 90);
						context.fillText(`拍摄位置：${cvsObj.address}`, 50, canvasHeight - 40);
						// 一定要加上一个定时器否则进入到页面第一次可能会无法正常拍照，后几次才正常
						setTimeout(() => {
							// 本次绘画完重开开始绘画，并且在绘画完毕之后再保存图片，不然页面可能会出现白屏等情况
							context.draw(false, () => {
								// console.log('!!!!!开始绘画', canvasWidth, canvasHeight);
								uni.canvasToTempFilePath({
									canvasId: "waterMarkCanvas",
									fileType: "jpg",
									width: canvasWidth,
									height: canvasHeight,
									destWidth: canvasWidth,
									destHeight: canvasHeight,
									success: ({
										tempFilePath
									}) => {
										waterMarkParams.display = false
										resolve(tempFilePath)
									},
									fail: err => {
										reject(err)
										console.log(err);
									}
								})
							})
						}, 1000);
					})
				}
			})
		})
	}

	onShow(async () => {
		await getDate()
		await getLocationFn()
	})

	onLoad(() => {})
</script>

<style lang="scss" scoped>
	:deep(.uni-file-picker__container) {
		.file-picker__box {
			height: 5.25rem !important;
			width: 33.3% !important;
		}
	}
</style>